package com.jackrain.nea.ext.permission;
import com.jackrain.nea.core.schema.TableManager;
import com.jackrain.nea.core.webaction.WebAction;

import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;

/**
 * @author lzm
 * @date 2017-11-17
 */
public class PermissionCollection implements Serializable {
    private static final long serialVersionUID = -6446479656205413976L;

    private HashMap<Long, MenuPermissionModel> menuCache = new HashMap<>();  //菜单项权限集合
    private HashMap<Long, ActionPermissionModel> actionCache = new HashMap<>(); //动作权限集合

    public PermissionCollection() {
    }

    public PermissionCollection(Collection<MenuPermissionModel> coll){
        addMenus(coll);
    }

    public void addMenus(Collection<MenuPermissionModel> menus){
        if(menus == null) {
            return;
        }
        for (MenuPermissionModel record: menus){
            addMenu(record);
        }
    }

    public void addMenu(MenuPermissionModel model){
        Long menuId = model.getAd_menu_id();
        if(menuCache.containsKey(menuId)){
            menuCache.put(menuId, MenuPermissionModel.union(menuCache.get(menuId), model));
        }
        else{
            menuCache.put(menuId, model);
        }
    }

    public void addActions(Collection<ActionPermissionModel> actions){
        if(actions == null) {
            return;
        }
        for (ActionPermissionModel record: actions){
            addAction(record);
        }
    }

    public void addAction(ActionPermissionModel model){
        Long actionId = model.getAd_action_id();
        if(actionCache.containsKey(actionId)){
            actionCache.put(actionId, ActionPermissionModel.union(actionCache.get(actionId), model));
        }
        else{
            actionCache.put(actionId, model);
        }
    }

    public ActionPermissionModel fetchActionById(Long actionId) {
        return actionCache.get(actionId);
    }

    public ActionPermissionModel fetchActionOrDefault(TableManager tm, MenuCollection tree, WebAction action, Long groupId){
        ActionPermissionModel result = fetchActionById((long)action.getId());
        if(result == null){
            result = createDefaultActionPermission(tm, tree, groupId, action);
        }
        return result;
}

    public MenuPermissionModel fetchMenuByMenuId(Long menuId){
        return menuCache.get(menuId);
    }



    public MenuPermissionModel fetchMenuOrDefault(MenuNode node, Long groupId){
        MenuPermissionModel result = fetchMenuByMenuId(node.getId());
        if(result == null)
        {
            result = createDefaultMenuPermission(groupId, node);
        }
        return  result;
    }

    public static PermissionCollection createEmptyCollection(){
        return  new PermissionCollection(null);
    }

    public MenuPermissionModel createFullMenuPermission(Long groupId, MenuNode node){
        MenuPermissionModel result = new MenuPermissionModel();
        result.setId(-1L);
        result.setAd_table_id(node.getAd_table_id());
        String mask = node.getMask();
        result.setMask(mask);
        result.setPermission(TableMaskHelper.convertToInt(mask));
        //result.setPermission(TableMaskHelper.ALL_PERMISSIONS);

//        if(node.getType() != null && node.getType() == MenuType.ACTION){
//            result.setPermission(TableMaskHelper.ALL_ACTION_PERMISSIONS);
//        }
        result.setAd_menu_id(node.getId());
        result.setName(node.getName());
        result.setDescription(node.getDescription());
        result.setType(node.getType());
        result.setGroupid(groupId);
        return result;
    }

    public MenuPermissionModel createDefaultMenuPermission(Long groupId, MenuNode node){
        MenuPermissionModel result = new MenuPermissionModel();
        result.setId(-1L);
        result.setAd_table_id(node.getAd_table_id());
        result.setPermission(0);
        result.setMask(node.getMask());
        result.setAd_menu_id(node.getId());
        result.setName(node.getName());
        result.setDescription(node.getDescription());
        result.setType(node.getType());
        result.setGroupid(groupId);
        return result;
    }

    public ActionPermissionModel createFullActionPermission(TableManager tm, MenuCollection tree, Long groupId, WebAction action) {
        ActionPermissionModel model = new ActionPermissionModel();
        Long actionId = (long)action.getId();
        model.setId(-1L);
        model.setGroupid(groupId);
        model.setAd_menu_id(-1L);
        model.setAd_action_id(actionId);
        //model.setMask(TableMaskHelper.ONLY_VIEW_MASK);
        String mask = TableMaskHelper.generateActionMask(tm, tree,actionId);
        model.setMask(mask);
        //model.setPermission(TableMaskHelper.ALL_ACTION_PERMISSIONS);
        model.setPermission(TableMaskHelper.convertToInt(mask));
        model.setType(MenuType.UNKNOWN);
        model.setName(action.getName());
        model.setDescription(action.getDescription());
        model.setAd_table_id((long)action.getTableId());
        return model;
    }

    public ActionPermissionModel createDefaultActionPermission(TableManager tm, MenuCollection tree, Long groupId, WebAction action) {
        ActionPermissionModel model = new ActionPermissionModel();
        Long actionId =(long)action.getId();
        model.setId(-1L);
        model.setGroupid(groupId);
        model.setAd_menu_id(-1L);
        model.setAd_action_id(actionId);
        model.setPermission(0);

        //model.setMask(TableMaskHelper.ONLY_VIEW_MASK);
        String mask = TableMaskHelper.generateActionMask(tm, tree,actionId);
        model.setMask(mask);
        model.setType(MenuType.UNKNOWN);
        model.setName(action.getName());
        model.setDescription(action.getDescription());
        model.setAd_table_id((long)action.getTableId());
        return model;
    }

    public static PermissionCollection Union(PermissionCollection left, PermissionCollection right){
        if(left instanceof AdminPermissionCollection){
            return left;
        }
        if(right instanceof AdminPermissionCollection){
            return right;
        }
        PermissionCollection result = createEmptyCollection();
        result.addMenus(left.menuCache.values());
        result.addMenus(right.menuCache.values());
        result.addActions(left.actionCache.values());
        result.addActions(right.actionCache.values());
        return result;
    }
}
